/*
* Copyright (C) 2012-2014 qar
* License: http://www.gnu.org/licenses/gpl.html GPL version 2
*/

#include <QtCore>

#include "extract.h"
#include "outputstream.h"
#include "store.h"
#include "util.h"
#include "crypto/cipher.h"

void showHelp()
{
    qErr() << "To create an archive from a directory, run: qar [-z level] directory_name. "
              "The archive directory_name.qar will be created.";
    qErr() << "Options:";
    qErr() << "    -z level: the zlib compression level (0 to 9). By default, use the zlib defaults (usually 6).";
    qErr() << "    -t: append a timestamp to the archive name.";
	qErr() << "    -c: encrypt the file.";
	qErr() << "    -k path: path to the file containing the encryption key. By default: ~/qar.key. Activates -c.";
	qErr() << "    -p: generate the encryption key file from a password.";
    qErr() << "";
    qErr() << "To extract an archive to the current directory, run: qar archive_name.qar. "
              "The directory archive_name will be created.";
}

QByteArray encodeFileNameUTF8(const QString &fileName)
{
    return fileName.toUtf8();
}

QString decodeFileNameUTF8(const QByteArray &localFileName)
{
    return QString::fromUtf8(localFileName);
}

int main(int argc, char **argv)
{
	QFile::setEncodingFunction(encodeFileNameUTF8);
    QFile::setDecodingFunction(decodeFileNameUTF8);

    argc--, argv++;

    int compressionLevel = -1;
    bool timestamp = false;
	bool encrypt = false;
	bool password = false;
	QString keyPath = QDir::homePath() + "/qar.key";
    QString arg;
    while (argc > 1) {
        arg = argv[0];
        if (arg == "-z") {
            argc--, argv++;
            if (argc <= 1) {
                qErr() << "Expecting integer argument between 0 and 9 after -z.";
                exit(-1);
            }
            arg = argv[0];
            argc--, argv++;
            bool ok;
            compressionLevel = arg.toInt(&ok);
            if (!ok || compressionLevel < 0 || compressionLevel > 9) {
                qErr() << "Expecting integer argument between 0 and 9 after -z.";
                exit(-1);
            }
        } else if (arg == "-t") {
            argc--, argv++;
            timestamp = true;
		} else if (arg == "-c") {
			argc--, argv++;
			encrypt = true;
		} else if (arg == "-k") {
			argc--, argv++;
			encrypt = true;
			if (argc <= 1) {
				qErr() << "Expecting string after -k.";
				exit(-1);
			}
			keyPath = argv[0];
			argc--, argv++;
		} else if (arg == "-p") {
			argc--, argv++;
			password = true;
			encrypt = true;
		}
    }

	if (password) {
		if (QFile::exists(keyPath)) {
			qErr() << "Key file already exists:" << keyPath;
			exit(-1);
		}
		fprintf(stdout, "Enter password:");
		fflush(stdout);
		char *line = NULL;
		size_t size = 0;
		if (getline(&line, &size, stdin) == -1) {
		    exit(-1);
		}
		QString password(line);
		free(line);
		password = password.trimmed();
		Cipher::generateKey(password.toUtf8(), 4096, keyPath);
	}

    if (argc != 1) {
        showHelp();
        exit(1);
    }

    arg = decodeFileNameUTF8(argv[0]);
    if (arg == "-h" ||
        arg == "--help" ||
        !QDir().exists(arg)) {
        showHelp();
        exit(0);
    }

    if (QDir().cd(arg)) {
		store(arg, compressionLevel, timestamp, encrypt, keyPath);
    } else {
		extract(arg, keyPath);
    }


    return 0;
}
